package com.xbongbong.pro.statistic.service.result;

import com.xbongbong.paas.elasticsearch.model.PaasEsModel;
import com.xbongbong.paas.elasticsearch.util.EsHelper;
import com.xbongbong.paas.help.CommonHelp;
import com.xbongbong.paas.model.PaasFormModel;
import com.xbongbong.paas.redis.PaasRedisHelper;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.thread.TransmittableThreadLocalUtil;
import com.xbongbong.pro.domain.entity.ChartEntity;
import com.xbongbong.pro.enums.SaasMarkEnum;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import com.xbongbong.pro.service.toolbox.statistic.help.ChartDtoHelp;
import com.xbongbong.pro.service.toolbox.statistic.help.ChartQueryHelp;
import com.xbongbong.pro.service.toolbox.statistic.help.ChartRuleQueryHelp;
import com.xbongbong.pro.service.toolbox.statistic.help.FormHelp;
import com.xbongbong.pro.service.toolbox.statistic.help.PerformanceHelp;
import com.xbongbong.pro.service.toolbox.statistic.help.PkHelp;
import com.xbongbong.pro.service.toolbox.statistic.help.PkRuleHelp;
import com.xbongbong.pro.service.toolbox.statistic.help.SystemChartHelp;
import com.xbongbong.pro.service.toolbox.statistic.help.ThroughHelp;
import com.xbongbong.pro.statistic.enums.PanoramaEnum;
import com.xbongbong.pro.statistic.enums.ReturnTypeEnum;
import com.xbongbong.pro.statistic.enums.SystemCodeEnum;
import com.xbongbong.pro.statistic.result.pojo.ChartResultPkPojo;
import com.xbongbong.pro.statistic.result.pojo.ChartResultPojo;
import com.xbongbong.pro.statistic.result.pojo.PanoramaPojo;
import com.xbongbong.pro.statistic.result.pojo.vo.ChartResultDetailVO;
import com.xbongbong.pro.statistic.result.pojo.vo.ChartResultPkDetailVO;
import com.xbongbong.pro.statistic.service.ChartResultProService;
import com.xbongbong.saas.constant.BasicConstant;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.saas.model.DataDictionaryModel;
import com.xbongbong.saas.service.toolbox.help.SaasListDataPermissionHelp;
import com.xbongbong.sys.domain.entity.UserEntity;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 获取统计结果父类
 * @author zcp
 * @version v1.0
 * @date 2019/4/19 15:28
 * @since v1.0
 */
@Component
public class ChartResult implements ChartResultProService {
    private static final Logger LOG = LoggerFactory.getLogger(ChartResult.class);

    @Resource
    protected ChartDtoHelp chartDtoHelp;
    @Resource
    protected ChartQueryHelp chartQueryHelp;
    @Resource
    protected ChartRuleQueryHelp chartRuleQueryHelp;
    @Resource
    protected SystemChartHelp systemChartHelp;
    @Resource
    protected EsHelper esHelper;
    @Resource
    protected PkHelp pkHelp;
    @Resource
    protected PkRuleHelp pkRuleHelp;
    @Resource
    protected FormHelp formHelp;
    @Resource
    protected CommonHelp commonHelp;
    @Resource
    protected ThroughHelp throughHelp;
    @Resource
    protected PerformanceHelp performanceHelp;
    @Resource
    protected DataDictionaryModel dataDictionaryModel;
    @Resource
    protected PaasFormModel paasFormModel;
    @Resource
    protected PaasRedisHelper paasRedisHelper;
    @Resource
    private CrmCustomerResult crmCustomerResult;
    @Resource
    private CrmCommunicateResult crmCommunicateResult;
    @Resource
    private CrmOpportunityResult crmOpportunityResult;
    @Resource
    private CrmContractResult crmContractResult;
    @Resource
    private CrmPaymentResult crmPaymentResult;
    @Resource
    private CrmInvoiceResult crmInvoiceResult;
    @Resource
    private CrmCallLogResult crmCallLogResult;
    @Resource
    private CrmProductResult crmProductResult;
    @Resource
    private CrmContactResult crmContactResult;
    @Resource
    private CrmRefundResult crmRefundResult;
    @Resource
    private CrmQuotationResult crmQuotationResult;
    @Resource
    private JxcPurchaseResult jxcPurchaseResult;
    @Resource
    private JxcPayResult jxcPayResult;
    @Resource
    private JxcStockResult jxcStockResult;
    @Resource
    private JxcProductionOrderResult jxcProductionOrderResult;
    @Resource
    private WorkOrderResult workOrderResult;
    @Resource
    private JxcInvoicePurchaseResult jxcInvoicePurchaseResult;
    @Resource
    private FundResult fundResult;
    @Resource
    private MarketActivityResult marketActivityResult;
    @Resource
    private MarketCLueResult marketCLueResult;
    @Resource
    private CrmOtherIncomeResult otherIncomeResult;
    @Resource
    private CrmOtherExpenseResult otherExpenseResult;
    @Resource
    protected SaasListDataPermissionHelp saasListDataPermissionHelp;
    @Resource
    protected PaasEsModel paasEsModel;

    @Override
    public List<Integer> businessType() {
        return Collections.singletonList(BasicConstant.ZERO);
    }

    /**
     * 获取系统指标的统计结果
     * @param returnTypeEnum 返回值类型枚举，如果为VALUE_RETURN，则为统计数值型;如果不为数值型，则传其他值即可
     * @param xbbRefTypeEnum 业务类型
     * @param chartResultPojo 请求系统指标接口需要用到的pojo类（内部存系统指标统计时需要的参数）
     * @param chartResultDetailVO 统计需要渲染的图（表---可能同时存在，可能某一个存在）塞入该vo
     * @return java.lang.Object
     * @throws XbbException
     * @author zcp
     * @date 2019/2/14 11:07
     * @since v1.0
     * @version v1.0
     */
    @Override
    public Object getResult4System(ReturnTypeEnum returnTypeEnum, XbbRefTypeEnum xbbRefTypeEnum, ChartResultPojo chartResultPojo, ChartResultDetailVO chartResultDetailVO) throws XbbException {
        ChartResultSystem chartResultSystem;

        switch (xbbRefTypeEnum) {
            case CUSTOMER_MANAGEMENT:
                chartResultSystem = crmCustomerResult;
                break;
            case CUSTOMER_COMMUNICATE:
                chartResultSystem = crmCommunicateResult;
                break;
            case SALES_OPPORTUNITY:
                chartResultSystem = crmOpportunityResult;
                break;
            case CONTRACT:
                chartResultSystem = crmContractResult;
                break;
            case PAYMENT:
                chartResultSystem = crmPaymentResult;
                break;
            case CONTACT:
                chartResultSystem = crmContactResult;
                break;
            case INVOICE:
                chartResultSystem = crmInvoiceResult;
                break;
            case PURCHASE_INVOICE:
                chartResultSystem = jxcInvoicePurchaseResult;
                break;
            case CALL_CENTER:
                chartResultSystem = crmCallLogResult;
                break;
            case PRODUCT:
                chartResultSystem = crmProductResult;
                break;
            case REFUND:
                chartResultSystem = crmRefundResult;
                break;
            case PAY_PLAN:
                chartResultSystem = jxcPayResult;
                break;
            case PURCHASE:
                chartResultSystem = jxcPurchaseResult;
                break;
            case PRODUCTION_ORDER:
                chartResultSystem = jxcProductionOrderResult;
                break;
            case WAREHOUSE:
                chartResultSystem = jxcStockResult;
                break;
            case WORK_ORDER:
                chartResultSystem = workOrderResult;
                break;
            case QUOTATION:
                chartResultSystem = crmQuotationResult;
                break;
            case FUND_MANAGEMENT:
                chartResultSystem = fundResult;
                break;
            case CLUE:
                chartResultSystem = marketCLueResult;
                break;
            case MARKET_ACTIVITY:
                chartResultSystem = marketActivityResult;
                break;
            case OTHER_INCOME:
                chartResultSystem = otherIncomeResult;
                break;
            case OTHER_EXPENSE:
                chartResultSystem = otherExpenseResult;
                break;
            default:
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100002, SystemErrorCodeEnum.API_ERROR_100002.getMsg());
        }
        if (returnTypeEnum == ReturnTypeEnum.VALUE_RETURN) {
            //单个数值型统计
            return chartResultSystem.getValueTarget(chartResultPojo);
        }else {
            //图表统计
            return chartResultSystem.getTarget(chartResultPojo, chartResultDetailVO);
        }
    }
    /**
     * 获取pk榜统计结果
     * @param userEntity 登录员工
     * @param xbbRefTypeEnum 业务类型
     * @param chartResultPkPojo pk参数
     * @return java.lang.Object
     * @throws XbbException
     * @author zcp
     * @date 2019/3/18 19:57
     * @since v1.0
     * @version v1.0
     */
    @Override
    public Object getResult4Pk(UserEntity userEntity, XbbRefTypeEnum xbbRefTypeEnum, ChartResultPkPojo chartResultPkPojo) throws XbbException {
        ChartResultPkDetailVO chartResultPkDetailVO = new ChartResultPkDetailVO();
        ChartResultPk chartResultPk;
        switch (xbbRefTypeEnum) {
            case CUSTOMER_MANAGEMENT:
                chartResultPk = crmCustomerResult;
                break;
            case CUSTOMER_COMMUNICATE:
                chartResultPk = crmCommunicateResult;
                break;
            case SALES_OPPORTUNITY:
                chartResultPk = crmOpportunityResult;
                break;
            case CONTRACT:
                chartResultPk = crmContractResult;
                break;
            case PAYMENT:
                chartResultPk = crmPaymentResult;
                break;
            case CONTACT:
                chartResultPk = crmContactResult;
                break;
            case PRODUCT:
                chartResultPk = crmProductResult;
                break;
            case QUOTATION:
                chartResultPk = crmQuotationResult;
                break;
            default:
                throw  new XbbException(SystemErrorCodeEnum.API_ERROR_100002, SystemErrorCodeEnum.API_ERROR_100002.getMsg());
        }
        TransmittableThreadLocalUtil.setValue(SaasMarkEnum.SAAS.getCode(), xbbRefTypeEnum.getCode(), null, null);
        return chartResultPk.getPkTarget(userEntity, chartResultPkPojo, chartResultPkDetailVO);
    }

    /**
     * 获取pk榜统计结果
     * @param userEntity 登录员工
     * @param xbbRefTypeEnum 业务类型
     * @param chartResultPkPojo pk参数
     * @return java.lang.Object
     * @throws XbbException
     * @author zcp
     * @date 2019/3/18 19:57
     * @since v1.0
     * @version v1.0
     */
    @Override
    public Object getResult4PkRule(UserEntity userEntity, ChartEntity chartEntity, XbbRefTypeEnum xbbRefTypeEnum, ChartResultPkPojo chartResultPkPojo) throws XbbException {
        ChartResultPkDetailVO chartResultPkDetailVO = new ChartResultPkDetailVO();
        ChartResultPk chartResultPk;
        switch (xbbRefTypeEnum) {
            case CUSTOMER_MANAGEMENT:
                chartResultPk = crmCustomerResult;
                break;
            case CUSTOMER_COMMUNICATE:
                chartResultPk = crmCommunicateResult;
                break;
            case SALES_OPPORTUNITY:
                chartResultPk = crmOpportunityResult;
                break;
            case CONTRACT:
                chartResultPk = crmContractResult;
                break;
            case PAYMENT:
                chartResultPk = crmPaymentResult;
                break;
            case CONTACT:
                chartResultPk = crmContactResult;
                break;
            case PRODUCT:
                chartResultPk = crmProductResult;
                break;
            case QUOTATION:
                chartResultPk = crmQuotationResult;
                break;
            case CLUE:
                chartResultPk = marketCLueResult;
                break;
            default:
                throw  new XbbException(SystemErrorCodeEnum.API_ERROR_100002, SystemErrorCodeEnum.API_ERROR_100002.getMsg());
        }
        TransmittableThreadLocalUtil.setValue(SaasMarkEnum.SAAS.getCode(), xbbRefTypeEnum.getCode(), null, null);
        return chartResultPk.getPkRuleTarget(userEntity, chartEntity, chartResultPkPojo, chartResultPkDetailVO);
    }

    /**
     * 获取系统指标统计结果（数值型）
     * @param systemCodeEnumList 要计算结果的系统指标枚举
     * @param chartResultPojo 统计请求参数pojo
     * @return java.util.Map<com.xbongbong.pro.statistic.enums.SystemCodeEnum,java.lang.String>
     * @throws XbbException
     * @author zcp
     * @date 2019/4/17 13:55
     * @since v1.0
     * @version v1.0
     */
    @Override
    public Map<SystemCodeEnum, String> getResult4SystemValue(List<SystemCodeEnum> systemCodeEnumList, ChartResultPojo chartResultPojo) throws XbbException {
        //key为系统指标枚举，value为该系统指标统计结果
        Map<SystemCodeEnum, String> systemResultMap = new HashMap<>(systemCodeEnumList.size());
        for (SystemCodeEnum systemCodeEnum : systemCodeEnumList) {
            chartResultPojo.setSystemCodeEnum(systemCodeEnum);
            //计算结果值
            String total = (String) getResult4System(ReturnTypeEnum.VALUE_RETURN, systemCodeEnum.getXbbRefTypeEnum(), chartResultPojo, null);
            systemResultMap.put(systemCodeEnum, total);
        }
        return systemResultMap;
    }

    /**
     * 获取全景指标统计结果
     * @param xbbRefTypeEnum 业务类型
     * @param panoramaPojo 全景指标请求参数pojo
     * @param panoramaEnum 全景指标枚举
     * @return java.lang.Object
     * @throws XbbException
     * @author zcp
     * @date 2019/6/3 11:20
     * @since v1.0
     * @version v1.0
     */
    @Override
    public Object getResult4Panorama(XbbRefTypeEnum xbbRefTypeEnum, PanoramaPojo panoramaPojo, PanoramaEnum panoramaEnum) throws XbbException {
        panoramaPojo.setPanoramaEnum(panoramaEnum);
        PanoramaResult panoramaResult;
        switch (xbbRefTypeEnum) {
            case CUSTOMER_MANAGEMENT:
                panoramaResult = crmCustomerResult;
                break;
            case CUSTOMER_COMMUNICATE:
                panoramaResult = crmCommunicateResult;
                break;
            case SALES_OPPORTUNITY:
                panoramaResult = crmOpportunityResult;
                break;
            case CONTRACT:
                panoramaResult = crmContractResult;
                break;
            case PAYMENT_MANAGEMENT:
                panoramaResult = crmPaymentResult;
                break;
            case CALL_CENTER:
                panoramaResult = crmCallLogResult;
                break;
            case QUOTATION:
                panoramaResult = crmQuotationResult;
                break;
            default:
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100002, SystemErrorCodeEnum.API_ERROR_100002.getMsg());
        }
        return panoramaResult.customer(panoramaPojo);
    }
}
